<?php

class LogicManager
{
	const ENGINES_CONFIG = 'ENGINES_CONFIG';
	const ENGINE_TYPE_RANK = 'rank';
	const ENGINE_TYPE_BACK_LIMK = 'backLink';
	
	const BACK_LINK_ENGINE_TYPE_DUMMY = 0;
	const RANK_ENGINE_TYPE_DUMMY = 0;
	const ISSUES_ENGINE_TYPE_DUMMY = 0;
	
	protected static $cache = array();
	 
	/**
	 * @return array<LogicEngine>
	 */
	protected static function getEngines($engineType)
	{
		if(isset(self::$cache[$engineType]))
			return self::$cache[$engineType];
			
		$config = Ezer_Config::get(self::ENGINES_CONFIG);
		if(!isset($config->$engineType))
			return array();
			
		$engines = array();
		$engineConfigs = $config->$engineType->toArray();
		foreach($engineConfigs as $engineConfig)
		{
			if(!isset($engineConfig->engineType))
			{
				Ezer_Log::err("Type not defined");
				continue;
			}
				
			if(!isset($engineConfig->class))
			{
				Ezer_Log::err("Class not defined");
				continue;
			}
				
			$type = $engineConfig->engineType;
			$class = $engineConfig->class;
			
			if(!class_exists($class))
			{
				Ezer_Log::err("Class [$class] doesn't exist");
				continue;
			}
			
			$engine = new $class($type, $engineConfig);
			$engines[$type] = $engine;
		}
		
		self::$cache[$engineType] = $engines;
		return $engines;
	}
	
	/**
	 * @return array<LogicRankEngine>
	 */
	protected static function getBackLinkEngines()
	{
		$engines = self::getEngines(self::ENGINE_TYPE_BACK_LIMK);
		foreach($engines as $index => $engine)
		{
			if(!($engine instanceof LogicBackLinkEngine))
			{
				Ezer_Log::err("Engine [" . get_class($engine) . "] is not instance of LogicBackLinkEngine");
				unset($engines[$index]);
			}
		}
				
		return $engines;
	}
	
	/**
	 * @return array<LogicRankEngine>
	 */
	protected static function getRankEngines()
	{
		$engines = self::getEngines(self::ENGINE_TYPE_RANK);
		foreach($engines as $index => $engine)
		{
			if(!($engine instanceof LogicRankEngine))
			{
				Ezer_Log::err("Engine [" . get_class($engine) . "] is not instance of LogicRankEngine");
				unset($engines[$index]);
			}
		}
				
		return $engines;
	}
	
	/**
	 * @param string $url
	 * @return array<SeoSiteBackLink>
	 */
	public static function getBackLinks($url)
	{
		$ret = array();
		
		$engines = self::getBackLinkEngines();
		foreach($engines as $engine)
		{
			$backLinks = $engine->process($url);
			if($backLinks && count($backLinks))
			{
				foreach($backLinks as $backLink)
				$ret[$backLink->getSrcUrl()] = $backLink;
			}
		}
		
		return $ret;
	}
	
	/**
	 * @param string $url
	 * @return array<SeoSiteRank>
	 */
	public static function getRanks($url)
	{
		$ret = array();
		
		$engines = self::getRankEngines();
		foreach($engines as $engine)
		{
			$rank = $engine->process($url);
			if($rank)
				$ret[] = $rank;
		}
		
		return $ret;
	}
	
	/**
	 * @param string $url
	 * @return array<SeoUrlIssue>
	 */
	public static function getIssues($url)
	{
		// return dummy data
		$ret = array();
		
		$issue = new SeoUrlIssue();
		$issue->setEngineType(self::ISSUES_ENGINE_TYPE_DUMMY);
		$issue->setSrc('Somewhere in your code, line ' . __LINE__);
		$issue->setFix('Do fix it');
		$ret[] = $issue;
		
		$issue = new SeoUrlIssue();
		$issue->setEngineType(self::ISSUES_ENGINE_TYPE_DUMMY);
		$issue->setSrc('Somewhere in your code, line ' . __LINE__);
		$issue->setFix('Do fix it');
		$ret[] = $issue;
		
		return $ret;
	}
}